package com.pig4cloud.pig.ads.gdt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pig.ads.config.SdkProperties;
import com.pig4cloud.pig.ads.gdt.service.*;
import com.pig4cloud.pig.ads.pig.mapper.gdt.GdtAdCreativeMapper;
import com.pig4cloud.pig.ads.pig.mapper.gdt.GdtAdgroupMapper;
import com.pig4cloud.pig.ads.pig.mapper.gdt.GdtDynamicCreativeMapper;
import com.pig4cloud.pig.ads.utils.DateUtils;
import com.pig4cloud.pig.api.entity.GdtDynamicCreative;
import com.pig4cloud.pig.api.enums.GdtPageTypeEnum;
import com.pig4cloud.pig.api.gdt.dto.*;
import com.pig4cloud.pig.api.gdt.entity.*;
import com.pig4cloud.pig.common.core.util.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 广点通-广告组 服务层实现
 *
 * @author hma
 * @date 2020-12-05
 */
@Log4j2
@Service
@RequiredArgsConstructor
public class GdtAdCopyServiceImpl implements IGdtAdCopyService {

	private final GdtAdgroupMapper gdtAdgroupMapper;

	private final IGdtAdCreativeService iGdtAdCreativeService;

	private final IGdtAdgroupService gdtAdgroupService;

	private final GdtAdCreativeMapper gdtAdCreativeMapper;

	private final SdkProperties sdkProperties;

	private final IGdtAdService gdtAdService;

	private final GdtAudiencePackageService gdtAudiencePackageService;

	private final GdtDynamicCreativeMapper gdtDynamicCreativeMapper;

	@Override
	public R copyAd(GdtAdCopyDto gdtAdCopyDto){
		//查询被复制广告组信息
		GdtAdgroup gdtAdgroup = gdtAdgroupMapper.selectById(gdtAdCopyDto.getAdgroupId());
		if(gdtAdgroup==null){
			return R.failed("广告不存在");
		}
		boolean isdy = !"0".equals(gdtAdCopyDto.getDynamicCreativeId());
		//判断创意类型（动态创意,自定义创意） 0为自定义创意
		List<Long> advCreativeIds = new ArrayList<>();
		List<GdtAdCreativeCreateDto> crlist = new ArrayList<>();
		if(!isdy){
			//创建成功的创意
			List<GdtAdCreative> clist = gdtAdCreativeMapper.getAdCreativeByGrupId(gdtAdCopyDto.getAdgroupId());
			if(CollectionUtils.isEmpty(clist)){
				return R.failed("广告无创意无法复制");
			}
			//创建创意
			for (GdtAdCreative a : clist) {
				try {
					GdtAdCreativeCreateDto creativeCreateDto = new GdtAdCreativeCreateDto();
					BeanUtils.copyProperties(a, creativeCreateDto);
					creativeCreateDto.setCampaignId(Long.parseLong(gdtAdCopyDto.getCampaignId()));
					creativeCreateDto.setAccountId(Long.parseLong(gdtAdCopyDto.getAccountId()));
					creativeCreateDto.setPageType(gdtAdCopyDto.getPageType());
					creativeCreateDto.setPageSpec(null);
					creativeCreateDto.setAdcreativeName(gdtAdCopyDto.getAdgroupName() + "copy");
					this.dealCreativeData(creativeCreateDto);
					this.dealCreativeElements(creativeCreateDto);
					if (!GdtPageTypeEnum.PAGE_TYPE_DEFAULT.getType().equals(gdtAdCopyDto.getPageType())) {
						Map map = new HashMap();
						map.put("page_id", gdtAdCopyDto.getPageId());
						creativeCreateDto.setPageSpec(JSON.toJSONString(map));
					}
					creativeCreateDto.setIsDynamicCreative("0");
					iGdtAdCreativeService.createGdtCreative(creativeCreateDto);
					crlist.add(creativeCreateDto);
					advCreativeIds.add(creativeCreateDto.getAdcreativeId());

				} catch (Throwable e) {
					log.error("创建广点通广告创意：" + (StringUtils.isBlank(e.getMessage()) ? "" : e.getMessage()));
					return R.failed("创建广点通广告创意：" + (StringUtils.isBlank(e.getMessage()) ? "" : e.getMessage()));
				}
			}
		}else {
			List<String> cids = Arrays.asList(gdtAdCopyDto.getDynamicCreativeId().split(","));
			List<GdtDynamicCreative> dylist = gdtDynamicCreativeMapper.selectBatchIds(cids);
			if(CollectionUtils.isEmpty(dylist)){
				return R.failed("广告无动态创意无法复制");
			}
			for (GdtDynamicCreative a : dylist) {
				try {
					GdtAdCreativeCreateDto creativeCreateDto = new GdtAdCreativeCreateDto();
					BeanUtils.copyProperties(a, creativeCreateDto);
					creativeCreateDto.setAdcreativeElements(a.getDynamicCreativeElements());
					creativeCreateDto.setAdcreativeTemplateId(a.getDynamicCreativeTemplateId());
					creativeCreateDto.setCampaignId(Long.parseLong(gdtAdCopyDto.getCampaignId()));
					creativeCreateDto.setAccountId(Long.parseLong(gdtAdCopyDto.getAccountId()));
					creativeCreateDto.setPageType(gdtAdCopyDto.getPageType());
					creativeCreateDto.setAdcreativeName(gdtAdCopyDto.getAdgroupName() + "copy");
					creativeCreateDto.setPageSpec(null);
					this.dealCreativeData(creativeCreateDto);
					this.dealCreativeElements(creativeCreateDto);
					creativeCreateDto.setIsDynamicCreative("1");
					if (!GdtPageTypeEnum.PAGE_TYPE_DEFAULT.getType().equals(gdtAdCopyDto.getPageType())) {
						Map map = new HashMap();
						map.put("page_id", gdtAdCopyDto.getPageId());
						creativeCreateDto.setPageSpec(JSON.toJSONString(map));
					}
					iGdtAdCreativeService.createGdtCreative(creativeCreateDto);
					crlist.add(creativeCreateDto);
					advCreativeIds.add(creativeCreateDto.getAdcreativeId());
				} catch (Throwable e) {
					log.error("创建广点通广告创意：" + (StringUtils.isBlank(e.getMessage()) ? "" : e.getMessage()));
					return R.failed("创建广点通广告创意：" + (StringUtils.isBlank(e.getMessage()) ? "" : e.getMessage()));
				}
			}
		}

		GdtAdgroupCreateTempDto gdtAdgroupCreateTempDto = new GdtAdgroupCreateTempDto();
		BeanUtils.copyProperties(gdtAdgroup, gdtAdgroupCreateTempDto);
		gdtAdgroupCreateTempDto.setCampaignId(Long.parseLong(gdtAdCopyDto.getCampaignId()));
		gdtAdgroupCreateTempDto.setAdgroupName(gdtAdCopyDto.getAdgroupName());
		gdtAdgroupCreateTempDto.setCopyFlag(true); //用来区分是复制
		gdtAdgroupCreateTempDto.setDynamicCreativeId(null);
		gdtAdgroupCreateTempDto.setDeepOptimizationActionType(null);
		if (gdtAdgroupCreateTempDto.getTargetingId() == 0) {
			gdtAdgroupCreateTempDto.setTargetingId(null);
		}
		//出价方式
		String bidMode = gdtAdgroupCreateTempDto.getBidMode();
		if (StringUtils.isNotBlank(bidMode) && !StringUtils.equals(bidMode, "BID_MODE_OCPM") && !StringUtils.equals(bidMode, "BID_MODE_OCPC")) {
			gdtAdgroupCreateTempDto.setBidStrategy(null);
			gdtAdgroupCreateTempDto.setAutoAcquisitionEnabled(null);
			gdtAdgroupCreateTempDto.setAutoAcquisitionBudget(null);
		}
		gdtAdgroupCreateTempDto.setConversionId(Long.parseLong(gdtAdCopyDto.getConversionId()));
		gdtAdgroupCreateTempDto.setAutoAcquisitionBudget(gdtAdgroup.getAutoAcquisitionBudget()==0?null:gdtAdgroupCreateTempDto.getAutoAcquisitionBudget());
		gdtAdgroupCreateTempDto.setBidAdjustment(deal(gdtAdgroupCreateTempDto.getBidAdjustment(),1));
		gdtAdgroupCreateTempDto.setExpandTargeting(deal(gdtAdgroupCreateTempDto.getExpandTargeting(),2));
		//处理开始日期，结束日期
		Date now = new Date();
		String nowStr = DateUtils.dateToString(now, DateUtils.YYYY_MM_DD);
		String beginDate = gdtAdgroupCreateTempDto.getBeginDate();
		String endDate = gdtAdgroupCreateTempDto.getEndDate();
		if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate)) {
			long days = DateUtils.getDaySub(beginDate, endDate);
			endDate = DateUtils.dateToString(DateUtils.addDays(now, (int) days), DateUtils.YYYY_MM_DD);
		}
		gdtAdgroupCreateTempDto.setBeginDate(nowStr);
		gdtAdgroupCreateTempDto.setEndDate(endDate);
		this.dealTargeting(gdtAdgroupCreateTempDto,gdtAdgroup.getAccountId());
		gdtAdgroupCreateTempDto.setAccountId(gdtAdgroup.getAccountId());
		gdtAdgroupCreateTempDto.setDeepConversionBehaviorBid(Integer.parseInt(gdtAdgroup.getDeepConversionBehaviorBid()));
		gdtAdgroupCreateTempDto.setAutomaticSiteEnabled(gdtAdgroup.getAutomaticSiteEnabled()?"1":"2");
		if(isdy){
			gdtAdgroupService.createGdtGroup(gdtAdgroupCreateTempDto,advCreativeIds);
		}else {
			gdtAdgroupService.createGdtGroup(gdtAdgroupCreateTempDto,null);
		}
		//创建广告
		List<GdtAdDto> gdtAdDtoList = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(crlist)){
			for (GdtAdCreativeCreateDto a : crlist) {
				String impressionTrackingUrl = null;
				String clickTrackingUrl = null;
				String feedsInteractionEnabled = null;
				GdtAdDto gdtAdDto = new GdtAdDto(a.getAccountId().toString(), a.getCampaignId(), gdtAdgroupCreateTempDto.getAdgroupId(), a.getAdcreativeId()
						, a.getAdcreativeName(), sdkProperties.getConfiguredStatus(), impressionTrackingUrl, clickTrackingUrl, feedsInteractionEnabled);
				//建创广告
				if(!isdy) {
					gdtAdService.createGdtAd(gdtAdDto);
				}
				gdtAdDtoList.add(gdtAdDto);
			}
		}

		//异步拉取广告创意
		ExecutorService es = new ThreadPoolExecutor(5, 5, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(50));
		es.submit(() -> {
			try {
				// 拉取广告组数据并存储
				if (null != gdtAdgroupCreateTempDto.getAdgroupId()) {
					gdtAdgroupService.getGdtGroup(gdtAdgroupCreateTempDto);
				}
				// 拉取数据存储,广告创意，广告
				GdtAdDto gdtAdDtoF =  new GdtAdDto();
				gdtAdDtoF.setAccountId(gdtAdCopyDto.getAccountId());
				if(!isdy) {
					gdtAdDtoF = gdtAdDtoList.get(0);
					if (gdtAdDtoList.size() > 1) {
						String adIds = gdtAdDtoList.stream().map(gdtAdDto -> gdtAdDto.getAdId().toString()).collect(Collectors.joining(","));
						gdtAdDtoF.setAdIds(adIds);
						gdtAdDtoF.setAdId(null);
						String adCreativeIds = gdtAdDtoList.stream().map(gdtAdDto -> gdtAdDto.getAdcreativeId().toString()).collect(Collectors.joining(","));
						gdtAdDtoF.setAdcreativeIds(adCreativeIds);
						gdtAdDtoF.setAdcreativeId(null);
					}
					gdtAdDtoF.setAdgroupId(null);
					//拉取广告
					gdtAdService.getGdtAdData(gdtAdDtoF);
				}else {
					gdtAdDtoF.setAdcreativeIds(advCreativeIds.stream().map(Object::toString).collect(Collectors.joining(",")));
				}
				//拉取创意
				iGdtAdCreativeService.getAdCreativeData(gdtAdDtoF,isdy);
			} catch (Exception e) {
				log.error("copy getad is error", e);
			}
		});
		return R.ok();
	}

	/**
	 * @Description: 处理struct结构体，{}的去掉。或去掉 []
	 * type 1.处理 {} 2处理[]
	 * @Author: zjz
	 * @Date: 2022/7/21
	 */
	private String deal(String str, int type){
		if (StringUtils.isBlank(str)) {
			return null;
		}
		switch (type){
			case 1:
				JSONObject jsonObject = JSONObject.parseObject(str);
				if (jsonObject.isEmpty()) {
					str = null;
				}
				break;
			case 2:
				JSONArray siteSetArr = JSONArray.parseArray(str);
				if (siteSetArr.isEmpty()) {
					str = null;
				}
				break;
			default:
				str = null;
				break;
		}
		return str;
	}

	private void dealCreativeData(GdtAdCreativeCreateDto creativeCreateDto) {
		//处理struct结构体，{}的去掉。
		creativeCreateDto.setShareContentSpec(deal(creativeCreateDto.getShareContentSpec(),1));

		creativeCreateDto.setDynamicAdcreativeSpec(deal(creativeCreateDto.getDynamicAdcreativeSpec(),1));

		creativeCreateDto.setLinkPageSpec(deal(creativeCreateDto.getLinkPageSpec(),1));

		creativeCreateDto.setSiteSet(deal(creativeCreateDto.getSiteSet(),2));
		//处理Long存储为0的数据
		Long componentId = creativeCreateDto.getComponentId();
		if (componentId != null && componentId == 0) {
			creativeCreateDto.setComponentId(null);
		}
		creativeCreateDto.setUnionMarketSwitch(null);
		creativeCreateDto.setAdcreativeId(null);
		creativeCreateDto.setMultiShareOptimizationEnabled(null);
		creativeCreateDto.setSimpleCanvasSubType(null);
		creativeCreateDto.setPlayablePageMaterialId(null);
		creativeCreateDto.setIsDeleted(null);
		creativeCreateDto.setCountdownSwitch(null);
		creativeCreateDto.setIsDynamicCreative(null);
		creativeCreateDto.setProfileId(null);
	}


	/**
	 * @Description: 处理人群包
	 * @Author: zjz
	 * @Date: 2022/7/22
	 */
	private void dealTargeting(GdtAdgroupCreateTempDto gdtAdgroupCreateTempDto, String sourceAccountId) {
		//新广告账户
		String accountId = gdtAdgroupCreateTempDto.getAccountId();
		//假如存在定向包id，且复制的账号变更，查询定向包详情赋到targeting，人群包置空
		Long targetingId = gdtAdgroupCreateTempDto.getTargetingId();
		//处理targeting为｛｝
		String targeting = deal(gdtAdgroupCreateTempDto.getTargeting(),1);

		if (StringUtils.isNotBlank(targeting)) {
			GdtAudiencePackage gdtAudiencePackage = JSON.parseObject(targeting, GdtAudiencePackage.class);
			if (gdtAudiencePackage == null) {
				return;
			}
			String behaviorOrInterest = gdtAudiencePackage.getBehaviorOrInterest();
			JSONObject behaviorOrInterestJsonObject = JSONObject.parseObject(behaviorOrInterest);
			if (behaviorOrInterestJsonObject != null && !behaviorOrInterestJsonObject.isEmpty()) {
				String behavior = behaviorOrInterestJsonObject.getString("behavior");
				if (StringUtils.isNotBlank(behavior)) {
					JSONArray behaviorJsonArray = JSONArray.parseArray(behavior);
					if (!behaviorJsonArray.isEmpty()) {
						IntStream.range(0, behaviorJsonArray.size()).forEach(i -> behaviorJsonArray.getJSONObject(i).put("targeting_tags", null));
						behaviorOrInterestJsonObject.put("behavior", behaviorJsonArray.toJSONString());
					}
				}
				String interest = behaviorOrInterestJsonObject.getString("interest");
				if (StringUtils.isNotBlank(interest)) {
					JSONObject interestJsonObject = JSONObject.parseObject(interest);
					if (interestJsonObject != null && !interestJsonObject.isEmpty()) {
						interestJsonObject.put("targeting_tags", null);
						behaviorOrInterestJsonObject.put("interest", interestJsonObject.toJSONString());
					}
				}
				gdtAudiencePackage.setBehaviorOrInterest(behaviorOrInterestJsonObject.toJSONString());
			}
			if (!accountId.equals(sourceAccountId)) {
				gdtAudiencePackage.setCustomAudience(null);
				gdtAudiencePackage.setExcludedCustomAudience(null);
			}
			gdtAdgroupCreateTempDto.setTargeting(JSON.toJSONString(gdtAudiencePackage));
			return;
		}
		if (targetingId != null && !accountId.equals(sourceAccountId)) {
			GdtAudiencePackage gdtAudiencePackage = gdtAudiencePackageService.getOne(Wrappers.<GdtAudiencePackage>query().lambda().eq(GdtAudiencePackage::getIdAdplatform, targetingId), false);
			if (gdtAudiencePackage == null) {
				return;
			}
			gdtAdgroupCreateTempDto.setTargetingId(null);
			gdtAudiencePackage.setCustomAudience(null);
			gdtAudiencePackage.setExcludedCustomAudience(null);
			GdtAudiencePackageDO entity = new GdtAudiencePackageDO();
			BeanUtils.copyProperties(gdtAudiencePackage, entity);
			gdtAdgroupCreateTempDto.setTargeting(JSON.toJSONString(entity));
			gdtAdgroupCreateTempDto.setExpandEnabled("false");
			gdtAdgroupCreateTempDto.setExpandTargeting(null);
		}
	}


	private void dealCreativeElements(GdtAdCreativeCreateDto creativeCreateDto) {
		String adcreativeElements = creativeCreateDto.getAdcreativeElements();
		//log.info("adcreativeElements=====>{}", adcreativeElements);
		if (StringUtils.isNotBlank(adcreativeElements)) {
			JSONObject jsonObject = JSONObject.parseObject(adcreativeElements);
			Long countdownExpiringTimestamp = jsonObject.getLong("countdown_expiring_timestamp");
			if (countdownExpiringTimestamp != null && countdownExpiringTimestamp <= 1000000000) {
				jsonObject.remove("countdown_expiring_timestamp");
			}
			creativeCreateDto.setAdcreativeElements(jsonObject.toJSONString());
		}
	}
}
